<?php
namespace app\user\model;

use think\Model;

class TryAuth extends Model {
    public const SHOW_CAPTCHA_TIME = 5; //尝试登录5次后需要验证
    public const RESET_TIME = 15 * 60; //重置的时间
    protected $pk = ['uid', 'ip'];

    /**
     * 清除过时的记录
     * @return void
     */
    public static function cleanOutdated() : void {
        self::where('time', '<', time() - self::RESET_TIME)->delete();
    }

    /**
     * 增加登录失败的事件
     * @param $ip
     * @param $uid
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function increaseTry(string $ip, int $uid) : void {
        self::cleanOutdated();

        $currentTime = time();
        $ip = inet_pton($ip);
        //先处理基于ip的
        $count = self::where(['ip' => $ip])->count();
        if($count > 0){ //存在记录则更新
            self::where([
                ['ip', '=', $ip],
            ])->inc('tries')->update([
                'time' => $currentTime,
            ]);
        } else {
            $record = new self;
            $record->save([
                'uid' => $uid,
                'ip' => $ip,
                'tries' => 1,
                'time' => $currentTime,
            ]);
        }
        //再处理基于用户的
        $count = self::where(['uid' => $uid])->count();
        if($count > 0){
            self::where([
                ['uid', '=', $uid],
                ['ip', '<>', $ip], //忽略同ip，因为已经处理过了
            ])->inc('tries')->update([
                'time' => $currentTime,
            ]);
        } else {
            $record = new self;
            $record->save([
                'uid' => $uid,
                'ip' => $ip,
                'tries' => 1,
                'time' => $currentTime,
            ]);
        }
    }

    /**
     * 获取尝试登录的次数
     * @param string $ip
     * @param int $uid
     * @return int
     */
    public static function getTryTimes(string $ip, int $uid) : int {
        self::cleanOutdated();

        $ip = inet_pton($ip);
        $tries = self::whereOr([
            ['ip', '=', $ip],
            ['uid', '=', $uid],
        ])->max('tries');
        if($tries){
            return $tries;
        } else {
            return 0;
        }
    }

    /**
     * 此次登录是否需要使用验证码
     * @param string $ip
     * @param integer $uid
     * @return bool
     */
    public static function shouldUseCaptcha(string $ip, int $uid) : bool {
        $tries = self::getTryTimes($ip, $uid);
        return $tries >= self::SHOW_CAPTCHA_TIME;
    }

    public function getIpAttr(?string $value) : ?string {
        if($value){
            return inet_ntop($value);
        } else {
            return $value;
        }
    }
}